package excel

import (
	"fmt"
	"github.com/xuri/excelize/v2"
	"strconv"
)

// ReadExcel 读取excel
func ReadExcel(filePath string, sheetName ...string) ([][]string, error) {
	sheet := "Sheet1"
	if len(sheetName) > 0 {
		sheet = sheetName[0]
	}
	ret := make([][]string, 0)
	f, err := excelize.OpenFile(filePath)
	if err != nil {
		return ret, err
	}
	ret, err = f.GetRows(sheet)
	if err != nil {
		return ret, err
	}
	return ret, nil
}

// ReadExcelHead 读取excel头
func ReadExcelHead(filePath string, sheetName ...string) ([]string, [][]string, error) {
	sheet := "Sheet1"
	if len(sheetName) > 0 {
		sheet = sheetName[0]
	}
	if sheet == "" {
		sheet = "Sheet1"
	}
	header := make([]string, 0)
	content := make([][]string, 0)

	f, err := excelize.OpenFile(filePath)
	if err != nil {
		return header, content, err
	}
	content, err = f.GetRows(sheet)
	if err != nil {
		return header, content, err
	}
	if len(content) > 0 {
		header = content[0]
	}
	content = append(content[:0], content[1:]...)
	return header, content, nil
}

// WriteFormat 写入格式
type WriteFormat struct {
	SheetName string
	Header    []string
	Contents  [][]interface{}
	IsActive  bool
	Config    struct {
		HeaderSetting *HeaderSetting
		RowSetting    *RowSetting
	}
}

// HeaderSetting 头部设置
type HeaderSetting struct {
	RowHeight      float64
	ColWidth       float64
	FillColor      []string
	Font           *Font
	Alignment      *Alignment
	MergeRangeCell []string
	HeaderRange    []string
}

// RowSetting 行设置
type RowSetting struct {
	Font      *Font
	Alignment *Alignment
	FillColor []string
}

// Alignment 对齐方式
type Alignment struct {
	Horizontal string
	Vertical   string
	WrapText   bool
}

// Font 字体设置
type Font struct {
	Color string
	Size  float64
}

// WriteExcel 写入文件
func WriteExcel(wfs []*WriteFormat, savePath string) error {
	f := excelize.NewFile()
	for i, wf := range wfs {
		if i == 0 {
			if wf.SheetName != "Sheet1" {
				f.SetSheetName("Sheet1", wf.SheetName)
			}
			if wf.IsActive == true {
				f.SetActiveSheet(0)
			}
		} else {
			index := f.NewSheet(wf.SheetName)
			if wf.IsActive == true {
				f.SetActiveSheet(index)
			}
		}

		headerDefaultStart := "A"
		headerDefaultEnd := Index2ExcelRow(len(wf.Header) - 1)
		if wf.Config.HeaderSetting != nil {
			if wf.Config.HeaderSetting.HeaderRange == nil || len(wf.Config.HeaderSetting.HeaderRange) != 2 {
				wf.Config.HeaderSetting.HeaderRange = []string{
					headerDefaultStart, headerDefaultEnd,
				}
			}

			if wf.Config.HeaderSetting.ColWidth != 0 {
				err := f.SetColWidth(wf.SheetName, wf.Config.HeaderSetting.HeaderRange[0], wf.Config.HeaderSetting.HeaderRange[1], wf.Config.HeaderSetting.ColWidth)
				if err != nil {
					return err
				}
			}

			if wf.Config.HeaderSetting.RowHeight != 0 {
				if wf.Config.HeaderSetting.RowHeight > excelize.MaxRowHeight {
					wf.Config.HeaderSetting.RowHeight = excelize.MaxRowHeight
				}
				err := f.SetRowHeight(wf.SheetName, 1, wf.Config.HeaderSetting.RowHeight)
				if err != nil {
					return err
				}
			}
			if len(wf.Config.HeaderSetting.MergeRangeCell) == 2 {
				err := f.MergeCell(wf.SheetName, wf.Config.HeaderSetting.MergeRangeCell[0], wf.Config.HeaderSetting.MergeRangeCell[1])
				if err != nil {
					return err
				}
			}
			styleSetting := &excelize.Style{}
			if wf.Config.HeaderSetting.FillColor != nil {
				styleSetting.Fill = excelize.Fill{
					Type:    "pattern",
					Pattern: 1,
					Color:   wf.Config.HeaderSetting.FillColor,
					Shading: 0,
				}
			}
			if wf.Config.HeaderSetting.Font != nil {
				styleSetting.Font = &excelize.Font{
					Color: wf.Config.HeaderSetting.Font.Color,
					Size:  wf.Config.HeaderSetting.Font.Size,
				}
			}

			if wf.Config.HeaderSetting.Alignment != nil {
				styleSetting.Alignment = &excelize.Alignment{
					Horizontal: wf.Config.HeaderSetting.Alignment.Horizontal,
					Vertical:   wf.Config.HeaderSetting.Alignment.Vertical,
					WrapText:   wf.Config.HeaderSetting.Alignment.WrapText,
				}
			}

			style, err := f.NewStyle(styleSetting)
			if err != nil {
				return err
			}
			err = f.SetCellStyle(wf.SheetName, fmt.Sprintf("%s1", wf.Config.HeaderSetting.HeaderRange[0]), fmt.Sprintf("%s1", wf.Config.HeaderSetting.HeaderRange[1]), style)
			if err != nil {
				return err
			}
		}

		_ = f.SetSheetRow(wf.SheetName, "A1", &wf.Header)

		dataRowStyleSetting := &excelize.Style{}
		if wf.Config.RowSetting != nil {
			dataRowStyleSetting.Alignment = &excelize.Alignment{
				Horizontal: wf.Config.RowSetting.Alignment.Horizontal,
				Vertical:   wf.Config.RowSetting.Alignment.Vertical,
			}
		}
		dateRowStyle, err := f.NewStyle(dataRowStyleSetting)
		if err != nil {
			return err
		}
		line := 2
		for _, content := range wf.Contents {
			lineStr := strconv.Itoa(line)
			err = f.SetCellStyle(wf.SheetName, "A"+lineStr, fmt.Sprintf("%s%s", Index2ExcelRow(len(wf.Header)-1), lineStr), dateRowStyle)
			if err != nil {
				return err
			}
			_ = f.SetSheetRow(wf.SheetName, "A"+lineStr, &content)
			line++
		}
	}
	if err := f.SaveAs(savePath); err != nil {
		return err
	}
	return nil
}

// Index2ExcelRow 索引转换excel
func Index2ExcelRow(index int) string {
	var Letters = []string{"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"}
	// index := 10000
	result := Letters[index%26]
	index = index / 26
	for index > 0 {
		index = index - 1
		result = Letters[index%26] + result
		index = index / 26
	}
	return result
}
